package com.wangsd.web.weixin.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.JsonObject;
import com.wangsd.common.component.WxComponentService;
import com.wangsd.common.utils.HttpClientUtils;
import com.wangsd.web.weixin.entity.WxComponentBind;
import com.wangsd.web.weixin.mapper.WxComponentBindMapper;
import com.wangsd.web.weixin.service.WxComponentBindService;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class WxComponentBindServiceImpl extends ServiceImpl<WxComponentBindMapper, WxComponentBind> implements WxComponentBindService {

    @Resource
    WxComponentBindMapper wxComponentBindMapper;

    @Autowired
    WxComponentService wxComponentService;

    @Override
    public void createAndBulid(Long merchantId, String platform, String appid, String miniAppid, String appSecret) throws Exception {
        try {
            //查询本地数据库得绑定关系
            QueryWrapper query = new QueryWrapper();
            query.eq("merchant_id", platform + merchantId);
            WxComponentBind bind = wxComponentBindMapper.selectOne(query);

            //本地存储不存在虚拟平台，默认创建虚拟平台
            if (bind == null) {
                //创建平台并绑定公众号
                JSONObject json = creatBind(appid);
                Integer code = json.getInteger("errcode");
                //创建虚拟平台成功且成功绑定公众号
                if (code == 0) {
                    String openAppid = json.getString("open_appid");
                    WxComponentBind wxComponentBind = new WxComponentBind();
                    wxComponentBind.setAppId1(appid);
                    wxComponentBind.setOpenAppid(openAppid);
                    wxComponentBind.setMerchantId(platform + merchantId);
                    wxComponentBind.setAppSecret(appSecret);
                    wxComponentBindMapper.insert(wxComponentBind);
                    //绑定小程序
                    bindingMini(miniAppid, openAppid, wxComponentBind);
                } else {//创建失败
                    //处理已经绑定平台问题
                    if (code == 89000) {
                        //查询绑定得信息
                        JSONObject bid = getBind(appid);
                        //执行解绑
                        String openAppid = bid.getString("open_appid");
                        unBind(appid, openAppid);

                        //删除本地绑定关系
                        QueryWrapper qw = new QueryWrapper();
                        qw.eq("app_id1", appid);
                        qw.eq("open_appid", openAppid);
                        wxComponentBindMapper.delete(qw);


                        //重新创建平台并绑定公众号
                        json = creatBind(appid);
                        code = json.getInteger("errcode");
                        if (code == 0) { //创建虚拟平台成功且成功绑定公众号
                            openAppid = json.getString("open_appid");
                            WxComponentBind wxComponentBind = new WxComponentBind();
                            wxComponentBind.setOpenAppid(openAppid);
                            wxComponentBind.setAppId1(appid);
                            wxComponentBind.setMerchantId(platform + merchantId);
                            wxComponentBind.setAppSecret(appSecret);
                            wxComponentBindMapper.insert(wxComponentBind);
                            //绑定小程序
                            bindingMini(miniAppid, openAppid, wxComponentBind);
                        } else {
                            //二次执行创建失败，直接返回
                            throw new Exception(json.getString("errmsg"));
                        }
                    } else {
                        throw new Exception(json.getString("errmsg"));
                    }
                }
            } else {
                //本地已存在 不做重复处理
            }
        } catch (WxErrorException e) {
            throw new Exception(e.getMessage());
        }
    }

    @Override
    public String selectSecrtByAppId(String appId) {
        QueryWrapper qw = new QueryWrapper();
        qw.eq("app_id1", appId);
        WxComponentBind wxComponentBind = wxComponentBindMapper.selectOne(qw);
        if (wxComponentBind != null && StringUtils.isNotBlank(wxComponentBind.getAppSecret())) {
            return wxComponentBind.getAppSecret();
        }
        return null;
    }

    private void bindingMini(String miniAppid, String openAppid, WxComponentBind wxComponentBind) throws Exception {
        JSONObject json = binding(miniAppid, openAppid);
        Integer code = json.getInteger("errcode");
        if (code == 0) {//绑定小程序成功
            wxComponentBind.setAppId2(miniAppid);
            wxComponentBindMapper.updateById(wxComponentBind);
        } else {
            if (code == 89000) {
                //查询绑定
                JSONObject bid = getBind(miniAppid);
                //执行解绑
                String oldOpenAppid = bid.getString("open_appid");
                unBind(miniAppid, oldOpenAppid);
                //删除本地绑定关系
                QueryWrapper qw = new QueryWrapper();
                qw.eq("app_id2", miniAppid);
                qw.eq("open_appid", oldOpenAppid);
                wxComponentBindMapper.delete(qw);

                //重新绑定小程序
                json = binding(miniAppid, openAppid);
                code = json.getInteger("errcode");
                if (code == 0) {//绑定小程序成功
                    wxComponentBind.setAppId2(miniAppid);
                    wxComponentBindMapper.updateById(wxComponentBind);
                } else {
                    throw new Exception(json.getString("errmsg"));
                }
            } else {
                throw new Exception(json.getString("errmsg"));
            }
        }
    }

    private void unBind(String appid, String openAppid) throws Exception {
        String url = "https://api.weixin.qq.com/cgi-bin/open/unbind?access_token=";
        String access_token = wxComponentService.getWxOpenComponentService().getAuthorizerAccessToken(appid, false);
        JsonObject param = new JsonObject();
        param.addProperty("appid", appid);
        param.addProperty("open_appid", openAppid);
        String str = HttpClientUtils.post(url + access_token, param.toString(), "utf-8");
        JSONObject json = JSONObject.parseObject(str);
        if (0 != json.getInteger("errcode")) {
            throw new Exception(json.getString("errmsg"));
        }
    }

    private JSONObject getBind(String appid) throws Exception {
        String url = "https://api.weixin.qq.com/cgi-bin/open/get?access_token=";
        String access_token = wxComponentService.getWxOpenComponentService().getAuthorizerAccessToken(appid, false);
        JsonObject param = new JsonObject();
        param.addProperty("appid", appid);
        String str = HttpClientUtils.post(url + access_token, param.toString(), "utf-8");
        JSONObject json = JSONObject.parseObject(str);
        if (0 != json.getInteger("errcode")) {
            throw new Exception(json.getString("errmsg"));
        }
        return json;
    }

    //创建并绑定
    private JSONObject creatBind(String appid) throws WxErrorException {
        String url = "https://api.weixin.qq.com/cgi-bin/open/create?access_token=";
        String access_token = wxComponentService.getWxOpenComponentService().getAuthorizerAccessToken(appid, false);
        JsonObject param = new JsonObject();
        param.addProperty("appid", appid);
        String str = HttpClientUtils.post(url + access_token, param.toString(), "utf-8");
        JSONObject json = JSONObject.parseObject(str);
        return json;
    }

    private JSONObject binding(String appid, String openAppid) throws WxErrorException {
        //绑定小程序
        String access_token = wxComponentService.getWxOpenComponentService().getAuthorizerAccessToken(appid, false);
        String url1 = "https://api.weixin.qq.com/cgi-bin/open/bind?access_token=";
        JsonObject param1 = new JsonObject();
        param1.addProperty("appid", appid);
        param1.addProperty("open_appid", openAppid);
        String str = HttpClientUtils.post(url1 + access_token, param1.toString(), "utf-8");
        JSONObject json = JSONObject.parseObject(str);
        return json;
    }
}
